package com.yboot.starter.common.core.web.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.yboot.starter.common.core.constant.CommonConstant;
import lombok.Data;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Data
public class Result<T> implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 返回处理消息
	 */
	private String msg = "success";

	/**
	 * 返回代码
	 */
	private Integer code = 0;
	
	/**
	 * 返回数据对象 data
	 */
	private T data;

	/**
	 * 额外数据
	 */
	@JsonInclude(JsonInclude.Include.NON_NULL)
	private Map<String, Object> ext;
	
	/**
	 * 时间戳
	 */
	private long timestamp = System.currentTimeMillis();

	public Result() {
	}

    /**
     * 兼容VUE3版token失效不跳转登录页面
     * @param code
     * @param msg
     */
	public Result(Integer code, String msg) {
		this.code = code;
		this.msg = msg;
	}
	
	public Result<T> success(String message) {
		this.msg = message;
		this.code = CommonConstant.OK;
		return this;
	}

	public static<T> Result<T> ok() {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		return r;
	}

	public static<T> Result<T> ok(String msg, T data) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		r.setData(data);
		r.setMsg(msg);
		return r;
	}

	public static<T> Result<T> ok(T data) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> OK() {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		return r;
	}

	/**
	 * 此方法是为了兼容升级所创建
	 *
	 * @param msg
	 * @param <T>
	 * @return
	 */
	public static<T> Result<T> OK(String msg) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		r.setMsg(msg);
		//Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D
		r.setData((T) msg);
		return r;
	}

	public static<T> Result<T> OK(T data) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> OK(String msg, T data) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.OK);
		r.setMsg(msg);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> error(String msg, T data) {
		Result<T> r = new Result<T>();
		r.setCode(CommonConstant.FAIL);
		r.setMsg(msg);
		r.setData(data);
		return r;
	}

	public static<T> Result<T> error(String msg) {
		return error(CommonConstant.FAIL, msg);
	}
	
	public static<T> Result<T> error(int code, String msg) {
		Result<T> r = new Result<T>();
		r.setCode(code);
		r.setMsg(msg);
		return r;
	}

	public Result<T> put(String key, Object value) {
		if (ext == null) {
			ext = new HashMap<>();
		}
		ext.put(key, value);
		return this;
	}
}